﻿using Microsoft.Xna.Framework;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using System.Linq;

namespace PenguinForce.Levels
{
    public class FadingLayer
    {

        public FadingLayer(Vector2 position, int radius, float duration, Grid grid, Tile.TileTypes tileType)
        {
            m_tiles = new List<Tile>();
            m_duration = duration * 1000;
            m_originalDuration = duration * 1000;
            m_radius = radius;

            CalculateTilePlacement(position, grid, tileType);

        }

        public void Update(GameTime gameTime)
        {
            // decrement duration
            float et = gameTime.ElapsedGameTime.Milliseconds;
            m_duration -= et;
            if (m_duration <= 0)
            {
                m_tiles.Clear();
            }
        }

        public void Draw(SpriteBatch sprite, GameTime gameTime)
        {
            for (int i = 0; i < m_tiles.Count; i++)
            {

                m_tiles[i].Draw(gameTime, sprite, m_duration / m_originalDuration);
            }
        }

        private void CalculateTilePlacement(Vector2 position, Grid grid, Tile.TileTypes type)
        {

            int gridX = (int)position.X / 32;
            int gridY = (int)position.Y / 32;

            IEnumerable<Vector2> distinctList = FindNearest(grid, gridX, gridY);
            Tile newTile;
            foreach (Vector2 pos in distinctList)
            {
                if (grid.m_grid[(int)pos.X, (int)pos.Y].m_tileType == Tile.TileTypes.Ice)
                {
                    newTile = new Tile(Grid.m_textureList);
                    newTile.m_location = new Vector2((int)pos.X * grid.GRIDSIZE, (int)pos.Y * grid.GRIDSIZE);
                    newTile.m_tileType = type;
                    m_tiles.Add(newTile);
                }
            }
        }

        private IEnumerable<Vector2> FindNearest(Grid grid, int x, int y)
        {
            List<Vector2> nearest = new List<Vector2>();
            nearest.Add(new Vector2(x, y));


            for (int i = 0; i < m_radius; i++)
            {
                int count = nearest.Count;
                for (int j = 0; j < count; j++)
                {
                    FindNearestCells(ref nearest, grid, (int)nearest[j].X, (int)nearest[j].Y);
                }


            }

            return nearest.Distinct();
        }

        public bool HasExpired()
        {
            if (m_duration < 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        private void FindNearestCells(ref List<Vector2> nearest, Grid grid, int x, int y)
        {

            /*
            for (int i = x - 1; i <= x + 1; i++)
            {
                for (int j = y - 1; j <= y + 1; j++)
                {
                    if (grid.OnGrid(i, j))
                    {
                        nearest.Add(new Vector2(i, j));
                    }

                }

            }*/

            if (grid.OnGrid(x - 1, y))
            {
                nearest.Add(new Vector2(x - 1, y));

            }
            if (grid.OnGrid(x + 1, y))
            {
                nearest.Add(new Vector2(x + 1, y));

            }
            if (grid.OnGrid(x, y - 1))
            {

                nearest.Add(new Vector2(x, y - 1));
            }
            if (grid.OnGrid(x, y + 1))
            {

                nearest.Add(new Vector2(x, y + 1));
            }

        }

        private float m_duration;
        private float m_originalDuration;
        private int m_radius;
        public List<Tile> m_tiles;
    }
}